library ieee;
use ieee.std_logic_1164.all;

use work.top_pkg.all;

entity top_tb is
end entity;

architecture bench of top_tb is

    -- component definition copied from top
    component top is
        generic (
            CYCLES_SEC : integer := 100e6;
            CYCLES_7_SEGMENT_REFRESH : integer := 16e5;
            MAX_SECS_LOG2 : integer := 16;
            LED_LOW : integer := 0;
            LED_HIGH : integer := 15;
            SEG_LOW : integer := 0;
            SEG_HIGH : integer := 3;
            SEG_MIN : integer := 0;
            SEG_MAX : integer := 6
        );
        port (
            -- general control signals
            clk : in std_logic;
            res : in std_logic;
            -- led controller signals
            led : out std_logic_vector(LED_HIGH downto LED_LOW);
            -- ssd controller signals
            seg_n : out std_logic_vector(SEG_MAX downto SEG_MIN);
            dp_n : out std_logic;
            an_n : out std_logic_vector(SEG_HIGH downto SEG_LOW)
        );
    end component;

    -- tb constants
    constant HALF_PERIOD : time := 5ns;

    -- top constants
    constant CYCLES_SEC : integer := 15; -- shorter for sim
    constant CYCLES_7_SEGMENT_REFRESH : integer := 15; -- shorter for sim
    constant MAX_SECS_LOG2 : integer := 4; -- fewer leds for sim
    constant LED_LOW : integer := 0;
    constant LED_HIGH : integer := 15;
    constant SEG_LOW : integer := 0;
    constant SEG_HIGH : integer := 3;
    constant SEG_MIN : integer := 0;
    constant SEG_MAX : integer := 6;

    -- tb signals
    -- these need default assignments (uut signals must be set correctly by unit itself)
    signal finished : boolean := false;
    -- general control signals
    signal clk : std_logic := '0';
    signal res : std_logic := '0';

    -- top signals
    -- led controller signals
    signal led : std_logic_vector(LED_HIGH downto LED_LOW);

    -- ssd controller signals
    signal seg_n : std_logic_vector(SEG_MAX downto SEG_MIN);
    signal dp_n : std_logic;
    signal an_n : std_logic_vector(SEG_HIGH downto SEG_LOW);

begin

    uut : top
    generic map (
        CYCLES_SEC => CYCLES_SEC,
        CYCLES_7_SEGMENT_REFRESH => CYCLES_7_SEGMENT_REFRESH,
        MAX_SECS_LOG2 => MAX_SECS_LOG2,
        LED_LOW => LED_LOW,
        LED_HIGH => LED_HIGH,
        SEG_LOW => SEG_LOW,
        SEG_HIGH => SEG_HIGH,
        SEG_MIN => SEG_MIN,
        SEG_MAX => SEG_MAX
    )
    port map (
        clk => clk,
        res => res,

        led => led,

        seg_n => seg_n,
        dp_n => dp_n,
        an_n => an_n
    );

    -- generate the test signal and stop
    put_uut : process
    begin
        finished <= false;
        --LED <= "0000000000000000"; -- should be done by reset
        res <= '1';
        wait for 10ns;
        res <= '0';
        wait for 10ms;
        finished <= true;
    end process;

    -- generate clk signal for test
    clk <= not clk after HALF_PERIOD when not finished else '0';

end bench;
